using DocumentCreationSystem.Models;
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 自适应执行控制器 - 实时监控和调整执行策略
    /// </summary>
    public class AdaptiveExecutionController
    {
        private readonly ILogger<AdaptiveExecutionController> _logger;
        private readonly IAIService _aiService;
        private readonly ConcurrentDictionary<string, ExecutionSession> _activeSessions;
        private readonly Timer _monitoringTimer;

        public AdaptiveExecutionController(
            ILogger<AdaptiveExecutionController> logger,
            IAIService aiService)
        {
            _logger = logger;
            _aiService = aiService;
            _activeSessions = new ConcurrentDictionary<string, ExecutionSession>();
            _monitoringTimer = new Timer(MonitorActiveSessions, null, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
        }

        /// <summary>
        /// 开始监控执行会话
        /// </summary>
        public async Task<string> StartMonitoringSessionAsync(ComprehensivePlan plan, Models.ExecutionContext context)
        {
            try
            {
                var sessionId = Guid.NewGuid().ToString();
                var session = new ExecutionSession
                {
                    Id = sessionId,
                    Plan = plan,
                    Context = context,
                    StartTime = DateTime.Now,
                    Status = ExecutionSessionStatus.Running,
                    AdaptiveSettings = await DetermineInitialAdaptiveSettingsAsync(plan)
                };

                _activeSessions[sessionId] = session;
                _logger.LogInformation($"开始监控执行会话: {sessionId}");

                return sessionId;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "开始监控执行会话失败");
                throw;
            }
        }

        /// <summary>
        /// 更新执行进度
        /// </summary>
        public async Task UpdateExecutionProgressAsync(string sessionId, ExecutionProgressUpdate update)
        {
            if (_activeSessions.TryGetValue(sessionId, out var session))
            {
                session.ProgressUpdates.Add(update);
                session.LastUpdateTime = DateTime.Now;

                // 分析是否需要调整执行策略
                var adjustmentNeeded = await AnalyzeAdjustmentNeedAsync(session, update);
                if (adjustmentNeeded.IsNeeded)
                {
                    await ApplyExecutionAdjustmentAsync(session, adjustmentNeeded);
                }
            }
        }

        /// <summary>
        /// 处理执行异常
        /// </summary>
        public async Task HandleExecutionExceptionAsync(string sessionId, ExecutionException exception)
        {
            if (_activeSessions.TryGetValue(sessionId, out var session))
            {
                session.Exceptions.Add(exception);
                _logger.LogWarning($"执行会话 {sessionId} 发生异常: {exception.Message}");

                // 自动恢复策略
                var recoveryAction = await DetermineRecoveryActionAsync(session, exception);
                await ExecuteRecoveryActionAsync(session, recoveryAction);
            }
        }

        /// <summary>
        /// 完成执行会话
        /// </summary>
        public async Task<ExecutionSessionSummary> CompleteSessionAsync(string sessionId, PlanExecutionResult result)
        {
            if (_activeSessions.TryRemove(sessionId, out var session))
            {
                session.Status = result.Status == ExecutionStatus.Completed 
                    ? ExecutionSessionStatus.Completed 
                    : ExecutionSessionStatus.Failed;
                session.EndTime = DateTime.Now;
                session.FinalResult = result;

                var summary = await GenerateSessionSummaryAsync(session);
                _logger.LogInformation($"执行会话完成: {sessionId}");

                return summary;
            }

            throw new InvalidOperationException($"执行会话不存在: {sessionId}");
        }

        /// <summary>
        /// 确定初始自适应设置
        /// </summary>
        private async Task<AdaptiveExecutionSettings> DetermineInitialAdaptiveSettingsAsync(ComprehensivePlan plan)
        {
            var settings = new AdaptiveExecutionSettings
            {
                MaxRetryAttempts = 3,
                RetryDelayMultiplier = 2.0,
                PerformanceThreshold = 0.8,
                ErrorRateThreshold = 0.1,
                AdaptationSensitivity = AdaptationSensitivity.Medium
            };

            // 根据计划复杂度调整设置
            var complexity = EvaluatePlanComplexity(plan);
            switch (complexity)
            {
                case PlanComplexity.Simple:
                    settings.AdaptationSensitivity = AdaptationSensitivity.Low;
                    settings.MaxRetryAttempts = 2;
                    break;
                case PlanComplexity.Complex:
                    settings.AdaptationSensitivity = AdaptationSensitivity.High;
                    settings.MaxRetryAttempts = 5;
                    break;
                case PlanComplexity.VeryComplex:
                    settings.AdaptationSensitivity = AdaptationSensitivity.High;
                    settings.MaxRetryAttempts = 7;
                    settings.ErrorRateThreshold = 0.15;
                    break;
            }

            return settings;
        }

        /// <summary>
        /// 分析是否需要调整
        /// </summary>
        private async Task<AdjustmentAnalysis> AnalyzeAdjustmentNeedAsync(ExecutionSession session, ExecutionProgressUpdate update)
        {
            var analysis = new AdjustmentAnalysis { IsNeeded = false };

            try
            {
                // 分析性能指标
                var performanceScore = CalculateCurrentPerformanceScore(session);
                if (performanceScore < session.AdaptiveSettings.PerformanceThreshold)
                {
                    analysis.IsNeeded = true;
                    analysis.ReasonCode = AdjustmentReasonCode.PerformanceDegradation;
                    analysis.Severity = AdjustmentSeverity.Medium;
                }

                // 分析错误率
                var errorRate = CalculateCurrentErrorRate(session);
                if (errorRate > session.AdaptiveSettings.ErrorRateThreshold)
                {
                    analysis.IsNeeded = true;
                    analysis.ReasonCode = AdjustmentReasonCode.HighErrorRate;
                    analysis.Severity = AdjustmentSeverity.High;
                }

                // 分析资源使用情况
                if (update.ResourceUsage != null && IsResourceUsageAbnormal(update.ResourceUsage))
                {
                    analysis.IsNeeded = true;
                    analysis.ReasonCode = AdjustmentReasonCode.ResourceConstraint;
                    analysis.Severity = AdjustmentSeverity.Medium;
                }

                // 使用AI分析复杂情况
                if (analysis.IsNeeded && session.AdaptiveSettings.AdaptationSensitivity == AdaptationSensitivity.High)
                {
                    analysis = await EnhanceAnalysisWithAIAsync(session, analysis);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分析调整需求失败");
            }

            return analysis;
        }

        /// <summary>
        /// 应用执行调整
        /// </summary>
        private async Task ApplyExecutionAdjustmentAsync(ExecutionSession session, AdjustmentAnalysis analysis)
        {
            try
            {
                _logger.LogInformation($"应用执行调整: {analysis.ReasonCode}");

                var adjustment = new ExecutionAdjustment
                {
                    Timestamp = DateTime.Now,
                    ReasonCode = analysis.ReasonCode,
                    Severity = analysis.Severity
                };

                switch (analysis.ReasonCode)
                {
                    case AdjustmentReasonCode.PerformanceDegradation:
                        await AdjustForPerformanceAsync(session, adjustment);
                        break;
                    case AdjustmentReasonCode.HighErrorRate:
                        await AdjustForErrorRateAsync(session, adjustment);
                        break;
                    case AdjustmentReasonCode.ResourceConstraint:
                        await AdjustForResourceConstraintAsync(session, adjustment);
                        break;
                }

                session.Adjustments.Add(adjustment);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "应用执行调整失败");
            }
        }

        /// <summary>
        /// 性能调整
        /// </summary>
        private async Task AdjustForPerformanceAsync(ExecutionSession session, ExecutionAdjustment adjustment)
        {
            // 减少并发度
            if (session.Plan.WorkflowPlan?.Strategy.MaxConcurrency > 1)
            {
                session.Plan.WorkflowPlan.Strategy.MaxConcurrency--;
                adjustment.Actions.Add("减少并发度到 " + session.Plan.WorkflowPlan.Strategy.MaxConcurrency);
            }

            // 增加超时时间
            session.Plan.WorkflowPlan.Strategy.Timeout = TimeSpan.FromMinutes(
                session.Plan.WorkflowPlan.Strategy.Timeout.TotalMinutes * 1.5);
            adjustment.Actions.Add("增加超时时间到 " + session.Plan.WorkflowPlan.Strategy.Timeout.TotalMinutes + " 分钟");
        }

        /// <summary>
        /// 错误率调整
        /// </summary>
        private async Task AdjustForErrorRateAsync(ExecutionSession session, ExecutionAdjustment adjustment)
        {
            // 增加重试次数
            session.AdaptiveSettings.MaxRetryAttempts++;
            adjustment.Actions.Add("增加重试次数到 " + session.AdaptiveSettings.MaxRetryAttempts);

            // 增加重试延迟
            session.AdaptiveSettings.RetryDelayMultiplier *= 1.5;
            adjustment.Actions.Add("增加重试延迟倍数到 " + session.AdaptiveSettings.RetryDelayMultiplier);
        }

        /// <summary>
        /// 资源约束调整
        /// </summary>
        private async Task AdjustForResourceConstraintAsync(ExecutionSession session, ExecutionAdjustment adjustment)
        {
            // 切换到顺序执行模式
            if (session.Plan.WorkflowPlan?.Strategy.Mode != ExecutionMode.Sequential)
            {
                session.Plan.WorkflowPlan.Strategy.Mode = ExecutionMode.Sequential;
                adjustment.Actions.Add("切换到顺序执行模式");
            }

            // 减少资源使用
            session.Plan.WorkflowPlan.Strategy.MaxConcurrency = 1;
            adjustment.Actions.Add("设置最大并发为1");
        }

        /// <summary>
        /// 确定恢复动作
        /// </summary>
        private async Task<RecoveryAction> DetermineRecoveryActionAsync(ExecutionSession session, ExecutionException exception)
        {
            var action = new RecoveryAction
            {
                Type = RecoveryActionType.Retry,
                MaxAttempts = session.AdaptiveSettings.MaxRetryAttempts,
                DelayBetweenAttempts = TimeSpan.FromSeconds(5)
            };

            // 根据异常类型确定恢复策略
            switch (exception.Type)
            {
                case ExecutionExceptionType.NetworkTimeout:
                    action.Type = RecoveryActionType.RetryWithDelay;
                    action.DelayBetweenAttempts = TimeSpan.FromSeconds(30);
                    break;
                case ExecutionExceptionType.ResourceExhausted:
                    action.Type = RecoveryActionType.ReduceLoad;
                    break;
                case ExecutionExceptionType.InvalidInput:
                    action.Type = RecoveryActionType.SkipAndContinue;
                    break;
                case ExecutionExceptionType.SystemError:
                    action.Type = RecoveryActionType.Restart;
                    break;
            }

            return action;
        }

        /// <summary>
        /// 执行恢复动作
        /// </summary>
        private async Task ExecuteRecoveryActionAsync(ExecutionSession session, RecoveryAction action)
        {
            try
            {
                _logger.LogInformation($"执行恢复动作: {action.Type}");

                switch (action.Type)
                {
                    case RecoveryActionType.Retry:
                        // 重试逻辑
                        break;
                    case RecoveryActionType.RetryWithDelay:
                        await Task.Delay(action.DelayBetweenAttempts);
                        // 重试逻辑
                        break;
                    case RecoveryActionType.ReduceLoad:
                        await AdjustForResourceConstraintAsync(session, new ExecutionAdjustment());
                        break;
                    case RecoveryActionType.SkipAndContinue:
                        // 跳过当前步骤继续执行
                        break;
                    case RecoveryActionType.Restart:
                        // 重启执行
                        break;
                }

                session.RecoveryActions.Add(action);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "执行恢复动作失败");
            }
        }

        /// <summary>
        /// 监控活跃会话
        /// </summary>
        private async void MonitorActiveSessions(object? state)
        {
            try
            {
                foreach (var session in _activeSessions.Values)
                {
                    if (session.Status == ExecutionSessionStatus.Running)
                    {
                        await CheckSessionHealthAsync(session);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "监控活跃会话失败");
            }
        }

        /// <summary>
        /// 检查会话健康状态
        /// </summary>
        private async Task CheckSessionHealthAsync(ExecutionSession session)
        {
            var timeSinceLastUpdate = DateTime.Now - session.LastUpdateTime;
            
            // 检查是否长时间无更新
            if (timeSinceLastUpdate > TimeSpan.FromMinutes(10))
            {
                _logger.LogWarning($"会话 {session.Id} 长时间无更新，可能存在问题");
                
                // 触发健康检查
                var healthCheck = new ExecutionProgressUpdate
                {
                    Timestamp = DateTime.Now,
                    Type = ProgressUpdateType.HealthCheck,
                    Message = "自动健康检查"
                };

                await UpdateExecutionProgressAsync(session.Id, healthCheck);
            }
        }

        /// <summary>
        /// 生成会话摘要
        /// </summary>
        private async Task<ExecutionSessionSummary> GenerateSessionSummaryAsync(ExecutionSession session)
        {
            var summary = new ExecutionSessionSummary
            {
                SessionId = session.Id,
                StartTime = session.StartTime,
                EndTime = session.EndTime ?? DateTime.Now,
                Status = session.Status,
                TotalAdjustments = session.Adjustments.Count,
                TotalRecoveryActions = session.RecoveryActions.Count,
                FinalPerformanceScore = CalculateCurrentPerformanceScore(session),
                FinalErrorRate = CalculateCurrentErrorRate(session)
            };

            // 生成详细分析
            summary.PerformanceAnalysis = await GeneratePerformanceAnalysisAsync(session);
            summary.RecommendationsForFuture = await GenerateRecommendationsAsync(session);

            return summary;
        }

        /// <summary>
        /// 计算当前性能分数
        /// </summary>
        private double CalculateCurrentPerformanceScore(ExecutionSession session)
        {
            if (!session.ProgressUpdates.Any())
                return 1.0;

            var recentUpdates = session.ProgressUpdates
                .Where(u => u.Timestamp > DateTime.Now.AddMinutes(-5))
                .ToList();

            if (!recentUpdates.Any())
                return 1.0;

            // 简单的性能计算逻辑
            var successfulUpdates = recentUpdates.Count(u => u.Type == ProgressUpdateType.StepCompleted);
            return (double)successfulUpdates / recentUpdates.Count;
        }

        /// <summary>
        /// 计算当前错误率
        /// </summary>
        private double CalculateCurrentErrorRate(ExecutionSession session)
        {
            if (!session.ProgressUpdates.Any())
                return 0.0;

            var recentUpdates = session.ProgressUpdates
                .Where(u => u.Timestamp > DateTime.Now.AddMinutes(-5))
                .ToList();

            if (!recentUpdates.Any())
                return 0.0;

            var errorUpdates = recentUpdates.Count(u => u.Type == ProgressUpdateType.StepFailed);
            return (double)errorUpdates / recentUpdates.Count;
        }

        /// <summary>
        /// 检查资源使用是否异常
        /// </summary>
        private bool IsResourceUsageAbnormal(ResourceUsageInfo resourceUsage)
        {
            return resourceUsage.CpuUsage > 90 || 
                   resourceUsage.MemoryUsage > 90 || 
                   resourceUsage.DiskUsage > 95;
        }

        /// <summary>
        /// 评估计划复杂度
        /// </summary>
        private PlanComplexity EvaluatePlanComplexity(ComprehensivePlan plan)
        {
            var score = 0;

            if (plan.CharacterPlan != null)
            {
                score += plan.CharacterPlan.Characters.Count;
                score += plan.CharacterPlan.Relationships.Count;
            }

            if (plan.WorkflowPlan != null)
            {
                score += plan.WorkflowPlan.Steps.Count;
                score += plan.WorkflowPlan.Dependencies.Count * 2;
            }

            return score switch
            {
                <= 5 => PlanComplexity.Simple,
                <= 15 => PlanComplexity.Medium,
                <= 30 => PlanComplexity.Complex,
                _ => PlanComplexity.VeryComplex
            };
        }

        /// <summary>
        /// 使用AI增强分析
        /// </summary>
        private async Task<AdjustmentAnalysis> EnhanceAnalysisWithAIAsync(ExecutionSession session, AdjustmentAnalysis analysis)
        {
            try
            {
                var prompt = $@"请分析以下执行会话的状态并提供调整建议：

会话ID：{session.Id}
当前状态：{session.Status}
运行时间：{DateTime.Now - session.StartTime}
调整次数：{session.Adjustments.Count}
异常次数：{session.Exceptions.Count}
当前问题：{analysis.ReasonCode}

请提供：
1. 问题严重程度评估
2. 建议的调整策略
3. 预期效果";

                var aiResponse = await _aiService.GenerateTextAsync(prompt, 1000, 0.7f);
                
                // 解析AI响应并更新分析结果
                if (aiResponse.Contains("严重") || aiResponse.Contains("critical"))
                {
                    analysis.Severity = AdjustmentSeverity.High;
                }

                analysis.AIRecommendation = aiResponse;
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "AI增强分析失败");
            }

            return analysis;
        }

        /// <summary>
        /// 生成性能分析
        /// </summary>
        private async Task<string> GeneratePerformanceAnalysisAsync(ExecutionSession session)
        {
            var totalTime = (session.EndTime ?? DateTime.Now) - session.StartTime;
            var adjustmentCount = session.Adjustments.Count;
            var recoveryCount = session.RecoveryActions.Count;

            return $@"执行性能分析：
- 总执行时间：{totalTime.TotalMinutes:F1} 分钟
- 自适应调整次数：{adjustmentCount}
- 恢复动作次数：{recoveryCount}
- 最终性能分数：{CalculateCurrentPerformanceScore(session):F2}
- 最终错误率：{CalculateCurrentErrorRate(session):F2}";
        }

        /// <summary>
        /// 生成未来建议
        /// </summary>
        private async Task<List<string>> GenerateRecommendationsAsync(ExecutionSession session)
        {
            var recommendations = new List<string>();

            if (session.Adjustments.Count > 3)
            {
                recommendations.Add("考虑在初始规划阶段增加更保守的设置");
            }

            if (session.RecoveryActions.Count > 2)
            {
                recommendations.Add("建议增强错误预防机制");
            }

            if (CalculateCurrentErrorRate(session) > 0.1)
            {
                recommendations.Add("建议优化步骤设计以减少错误率");
            }

            return recommendations;
        }

        public void Dispose()
        {
            _monitoringTimer?.Dispose();
        }
    }
}
